package zookeeper.client;

import lombok.extern.slf4j.Slf4j;
import org.apache.zookeeper.KeeperException;
import org.apache.zookeeper.Watcher;
import org.apache.zookeeper.ZooDefs;
import org.apache.zookeeper.ZooKeeper;
import org.apache.zookeeper.server.util.ConfigUtils;
import zookeeper.utils.YamlUtil;

import java.io.IOException;
import java.util.Scanner;
import java.util.concurrent.CountDownLatch;

/**
 * @author zhenzicheng
 * @DESCRIPTION: 手动实现配置动态更新
 * @DATE: 2022/04/23 12:55 PM
 */
@Slf4j
public class ReconfigApp {
  private static final String CONNECT_STR;
  private static final int SESSION_TIMEOUT = 5 * 1000;
  private static final CountDownLatch countDownLatch = new CountDownLatch(1);
  private static ZooKeeper zooKeeper = null;
  /**
   * watcher
   */
  private static Watcher watcher = (event) -> {
    if (event.getType() == Watcher.Event.EventType.None
        && event.getState() == Watcher.Event.KeeperState.SyncConnected) {
      countDownLatch.countDown();
      log.info("连接建立");
      // start to watch config
      try {
        log.info("开始监听:{}", ZooDefs.CONFIG_NODE);
        // 将创建zookeeper对象时使用的监听器继续使用
        zooKeeper.getConfig(true, null);
      } catch (InterruptedException | KeeperException e) {
        e.printStackTrace();
      }
    } else if (event.getPath() != null && event.getPath().equals(ZooDefs.CONFIG_NODE)) {
      try {
        byte[] config = zooKeeper.getConfig(true, null);
        String clientConfigStr = ConfigUtils.getClientConfigStr(new String(config));
        log.info("配置发生变更:{}", clientConfigStr);
        zooKeeper.updateServerList(clientConfigStr.split(" ")[1]);
      } catch (IOException | KeeperException | InterruptedException e) {
        e.printStackTrace();
      }
    }
  };

  static {
    CONNECT_STR = YamlUtil.getDefaultClusterConnectStr();
  }

  public static void main(String[] args) throws InterruptedException, KeeperException, IOException {
    zooKeeper = new ZooKeeper(CONNECT_STR, SESSION_TIMEOUT, watcher);
    countDownLatch.await();

    Scanner scanner = new Scanner(System.in);
    while (true) {
      byte[] data = zooKeeper.getData("/zookeeper/config", true, null);
      scanner.next();
      log.info("DATA: {}", new String(data));
    }
  }

}
